/**
 * 作者查找类
 * findaPage方法用于查找作者所在的分页
 * findaLine方法用于查找作者所在的位置
 * finda方法用于查找与作者有关联的文章
 * readFile和writeFile方法用于初始化
 */


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Iterator;

public class AuthorFinder {

    /**
     * 内部类Index
     * 用于记录检索信息
     */
    public class Index{
        private int indexnum;  //索引数
        private String aname;  //名字
        public Index(String indexnum,String aname){
            this.indexnum=Integer.parseInt(indexnum);
            this.aname=aname;
        }

        //获得索引数
        public int getIndexnum(){
            return this.indexnum;
        }

        //获得标题
        public String getAname(){
            return this.aname;
        }
    }
    
    /**
     * 节点类
     * 用于记录读取到的任意行的信息
     */
    public class Node{
        private String name="";
        private List<Integer> p=new ArrayList<Integer>();
        //初始化name和p
        public Node(String name,List<Integer> p){
            this.name=name;
            for(int element:p){
                this.p.add(element);
            }
        }
        //获取name
        public String getName(){
            return this.name;
        }
        //获取p
        public List<Integer> getP(){
            return this.p;
        }
    }

    private String filepath="";
    private HashMap<String,List<Integer>> map=new HashMap<>();

    public AuthorFinder(){
        //初始化索引则取消下面两行的注释
        //readFile();
        //writeFile();
    }

    /**
     * 查找作者名所在分页的方法
     */
    public int findaPage(String path,String s){
        List<Index> lis=new ArrayList<Index>();
        try{
            File secindex = new File(path);
            BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(secindex),"utf-8"));
            String line="";
            while((line=br.readLine())!=null){
                String[] strarray=line.split(" ", 2);
                Index tempi=new Index(strarray[0],strarray[1]);
                lis.add(tempi);
            }
            br.close();
        }catch(IOException e){
            e.printStackTrace();
        }
        int i1=0;
        while(s.compareTo(lis.get(i1).getAname())>=0) {
        	i1++;
        }  //线性查找作者所在的分页
        return lis.get(i1-1).getIndexnum();  //返回页数+1
        
    }

    /**
     * 查找记录在有序记录集合中的位置
     */
    public List<Integer> findaLine(String s){
        int i=findaPage("./data/author/asecindex.txt",s);
        String path="./data/author/aindex_"+i+".txt";
        Node[] li=new Node[10000];
        int j=0;
        try{
            File page=new File(path);
            BufferedReader brl=new BufferedReader(new InputStreamReader(new FileInputStream(page),"utf-8"));
            String line="";
            while((line=brl.readLine())!=null){
                String n="";
                List<Integer> l=new ArrayList<Integer>();
                String[] strarray=line.split("#");
                for(int k=0;k<strarray.length;k++){
                    if(k==0) n=strarray[k];
                    else l.add(Integer.parseInt(strarray[k]));
                }
                li[j]=new Node(n,l);
                j++;
            }
            brl.close();
        }catch(IOException e){
            e.printStackTrace();
        }
        //折半查找
        int left=0,right=j-1; 
        while(left<=right){
            int mid=(left+right)/2;
            if(s.compareTo(li[mid].getName())==0){
                return li[mid].getP();  //若找到则返回作者关联文章的位置编号
            }else if(s.compareTo(li[mid].getName())>0){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return null;  //若未找到则返回null到调用点
    }

    /**
     * 在有序集合中查找记录
     */
    public List<String> finda(String s){
         List<Integer> li=findaLine(s);
         List<String> re=new ArrayList<String>();  //列表用于存储结果
         //完成记录存在的判断
         if(li==null){
             return null;  //若不在记录中，则返回null
         }
         for(int ele:li){
             int p=(ele-1)/10000;
             int r=ele%10000;
             String path="./data/paging/page_"+p+".txt";
             String line="";
             try{
                 File txt=new File(path);
                 BufferedReader brt=new BufferedReader(new InputStreamReader(new FileInputStream(txt),"utf-8"));
                 for(int i=0;i<r;i++){
                    line=brt.readLine();
                 }
                 brt.close();
             }catch(IOException e){
                 e.printStackTrace();
             }
             String[] str=line.split("\\|");
             re.add(str[0]);
         }
         return re;  //若在则返回结果
    }

    /**
     * 读取文件，利用hashmap创建索引
     */
    public void readFile(){
        int i=1;
        for(int j=0;j<219;j++){
            filepath="./data/paging/page_"+j+".txt";
            try{
            File txt=new File(filepath);
            BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(txt),"utf-8"));
            String line="";
            while((line=br.readLine())!=null){
                String[] strarray=line.split("\\|");
                String[] author=strarray[1].split("#");
                for(String name:author){
                    if(map.get(name)!=null){
                        map.get(name).add(i);
                    }else{
                        
                            List<Integer> li=new ArrayList<Integer>();
                            li.add(i);
                            map.put(name,li);
                        
                    }
                }
                i++;
            }
            br.close();
        }catch(IOException e){
            e.printStackTrace();
        }
        }
    }
    /**
     * 把hashmap中的内容写进记录文件中
     */
    public void writeFile(){
        File wfolder=new File("./data/author");
        if(!(wfolder.exists())){
            wfolder.mkdir();
        }
        File wtxt=new File("./data/author/author.txt");
        if(!(wtxt.exists())){
            try{
                wtxt.createNewFile();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
        try{
            BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(wtxt),"utf-8"));
            Iterator<String> it=map.keySet().iterator();
            while(it.hasNext()){
                String name=it.next();
                List<Integer> li=map.get(name);
                Iterator<Integer> its=li.iterator();
                String lin="";
                while(its.hasNext()){
                    lin+=("#"+its.next());
                }
                bw.write(name+lin+"\n");
                bw.flush();
            }
            bw.close();
        }catch(IOException e){
            e.printStackTrace();
        }    
    }
}